diff options
author | Ariya Hidayat <ariya.hidayat@nokia.com> | 2008-09-10 17:43:17 +0000 |
---|---|---|
committer | David Boddie <dboddie@trolltech.com> | 2008-09-10 17:43:17 +0000 |
commit | 9269160fdc7a9d08cce5b380868b1a83734b78bb (patch) | |
tree | 1f8b200cefb5ae389a0e563de5ecebf94a569465 | |
parent | 5a60ad83c5cea7d74a28005e64bf9f821959f25d (diff) |
Add image tinting example.
-rw-r--r-- | imagetint/berry.jpg | bin | 0 -> 501881 bytes | |||
-rw-r--r-- | imagetint/imagetint.cpp | 186 | ||||
-rw-r--r-- | imagetint/imagetint.pro | 5 | ||||
-rw-r--r-- | imagetint/imagetint.qrc | 5 | ||||
-rw-r--r-- | imagetint/parameters.ui | 393 |
5 files changed, 589 insertions, 0 deletions
diff --git a/imagetint/berry.jpg b/imagetint/berry.jpg Binary files differnew file mode 100644 index 0000000..fcc5034 --- /dev/null +++ b/imagetint/berry.jpg diff --git a/imagetint/imagetint.cpp b/imagetint/imagetint.cpp new file mode 100644 index 0000000..c9170d7 --- /dev/null +++ b/imagetint/imagetint.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the Graphics Dojo project on Trolltech Labs. +** +** This file may be used under the terms of the GNU General Public +** License version 2.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of +** this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** http://www.trolltech.com/products/qt/opensource.html +** +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://www.trolltech.com/products/qt/licensing.html or contact the +** sales department at sales@trolltech.com. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include <QtGui> + +#include "ui_parameters.h" + +class ImageTint: public QWidget +{ +public: + ImageTint(); + void loadImage(const QString &file); + void loadImage(const QImage &image); + +protected: + void dragEnterEvent(QDragEnterEvent*); + void dropEvent(QDropEvent *event); + void paintEvent(QPaintEvent*); + +private: + QString m_fileName; + QImage m_image; + Ui::ParametersForm parameters; +}; + +ImageTint::ImageTint() +{ + setAcceptDrops(true); + + setAttribute(Qt::WA_StaticContents, true); + setAttribute(Qt::WA_OpaquePaintEvent, true); + setAttribute(Qt::WA_NoSystemBackground, true); + + QWidget* toolWidget = new QWidget(this); + toolWidget->setWindowFlags(Qt::Tool | Qt::WindowTitleHint); + parameters.setupUi(toolWidget); + toolWidget->show(); + toolWidget->adjustSize(); + + connect(parameters.grayscaleButton, SIGNAL(toggled(bool)), this, SLOT(update())); + connect(parameters.tintButton, SIGNAL(toggled(bool)), this, SLOT(update())); + connect(parameters.redSlider, SIGNAL(valueChanged(int)), this, SLOT(update())); + connect(parameters.greenSlider, SIGNAL(valueChanged(int)), this, SLOT(update())); + connect(parameters.blueSlider, SIGNAL(valueChanged(int)), this, SLOT(update())); + connect(parameters.compositionModeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(update())); + + parameters.redSlider->setValue(0); + parameters.greenSlider->setValue(0); + parameters.blueSlider->setValue(96); +} + +void ImageTint::loadImage(const QImage &image) +{ + m_image = image; + if (m_image.isNull()) { + setFixedSize(512, 256); + setWindowTitle(QString("Can not load %1").arg(m_fileName)); + } else { + QString title = "Image Tint "; + if ((m_image.width() > 1024) || (m_image.height() > 800)) { + qDebug() << "Image is too large. Rescaling...."; + int w = m_image.width(); + m_image = m_image.scaled(640, 480, Qt::KeepAspectRatio, Qt::SmoothTransformation); + title += QString("[Zoom %1%] ").arg(m_image.width() * 100 / w); + } + setWindowTitle(QString("%1: %2 (%3 x %4)").arg(title).arg(m_fileName). + arg(m_image.width()).arg(m_image.height())); + setFixedSize(m_image.width(), m_image.height()); + } + update(); +} + +void ImageTint::loadImage(const QString &fileName) +{ + m_fileName = QFileInfo(fileName).fileName(); + loadImage(QImage(fileName)); +} + +void ImageTint::dragEnterEvent(QDragEnterEvent *event) +{ + if (event->mimeData()->hasFormat("text/uri-list")) + event->acceptProposedAction(); +} + +void ImageTint::dropEvent(QDropEvent *event) +{ + QList<QUrl> urls = event->mimeData()->urls(); + if (urls.count()) { + QString fname = urls[0].toLocalFile(); + if (event->mimeData()->hasImage()) { + QImage img = qvariant_cast<QImage>(event->mimeData()->imageData()); + m_fileName = QFileInfo(fname).fileName(); + loadImage(img); + } else + loadImage(fname); + event->acceptProposedAction(); + } +} + +// Convert an image to grayscale and return it as a new image +QImage grayscaled(const QImage &image) +{ + QImage img = image; + int pixels = img.width() * img.height(); + unsigned int *data = (unsigned int *)img.bits(); + for (int i = 0; i < pixels; ++i) { + int val = qGray(data[i]); + data[i] = qRgba(val, val, val, qAlpha(data[i])); + } + return img; +} + +// Tint an image with the specified color and return it as a new image +QImage tinted(const QImage &image, const QColor &color, QPainter::CompositionMode mode = QPainter::CompositionMode_Screen) +{ + QImage resultImage(image.size(), QImage::Format_ARGB32_Premultiplied); + QPainter painter(&resultImage); + painter.drawImage(0, 0, grayscaled(image)); + painter.setCompositionMode(mode); + painter.fillRect(resultImage.rect(), color); + painter.end(); + resultImage.setAlphaChannel(image.alphaChannel()); + + return resultImage; +} + +void ImageTint::paintEvent(QPaintEvent*) +{ + QPainter painter(this); + + if (parameters.noEffectButton->isChecked()) + painter.drawImage(0, 0, m_image); + + if (parameters.grayscaleButton->isChecked()) + painter.drawImage(0, 0, grayscaled(m_image)); + + if (parameters.tintButton->isChecked()) { + QColor tintColor; + tintColor.setRed(parameters.redSlider->value()); + tintColor.setGreen(parameters.greenSlider->value()); + tintColor.setBlue(parameters.blueSlider->value()); + + QPainter::CompositionMode table[] = { + QPainter::CompositionMode_Screen, + QPainter::CompositionMode_Overlay, + QPainter::CompositionMode_Multiply + }; + QPainter::CompositionMode mode = table[parameters.compositionModeBox->currentIndex()]; + + painter.drawImage(0, 0, tinted(m_image, tintColor, mode)); + } +} + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + ImageTint widget; + widget.show(); + if (argc > 1) + widget.loadImage(argv[1]); + else + widget.loadImage(":/berry.jpg"); + + return app.exec(); +} diff --git a/imagetint/imagetint.pro b/imagetint/imagetint.pro new file mode 100644 index 0000000..0a45389 --- /dev/null +++ b/imagetint/imagetint.pro @@ -0,0 +1,5 @@ +TEMPLATE = app +TARGET = imagetint +SOURCES = imagetint.cpp +RESOURCES = imagetint.qrc +FORMS = parameters.ui diff --git a/imagetint/imagetint.qrc b/imagetint/imagetint.qrc new file mode 100644 index 0000000..b75bd43 --- /dev/null +++ b/imagetint/imagetint.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource> + <file>berry.jpg</file> + </qresource> +</RCC> diff --git a/imagetint/parameters.ui b/imagetint/parameters.ui new file mode 100644 index 0000000..1ac08d9 --- /dev/null +++ b/imagetint/parameters.ui @@ -0,0 +1,393 @@ +<ui version="4.0" > + <class>ParametersForm</class> + <widget class="QWidget" name="ParametersForm" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>290</width> + <height>204</height> + </rect> + </property> + <property name="windowTitle" > + <string>Parameters</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2" > + <item> + <widget class="QWidget" native="1" name="widget" > + <layout class="QVBoxLayout" name="verticalLayout" > + <property name="margin" > + <number>0</number> + </property> + <item> + <widget class="QRadioButton" name="noEffectButton" > + <property name="text" > + <string>No Effect</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="grayscaleButton" > + <property name="text" > + <string>Grayscale</string> + </property> + </widget> + </item> + <item> + <widget class="QRadioButton" name="tintButton" > + <property name="text" > + <string>Tint</string> + </property> + <property name="checked" > + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" native="1" name="optionsWidget" > + <layout class="QGridLayout" name="gridLayout" > + <property name="margin" > + <number>0</number> + </property> + <item row="0" column="0" > + <widget class="QLabel" name="label_5" > + <property name="text" > + <string>Red</string> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="QSlider" name="redSlider" > + <property name="maximum" > + <number>255</number> + </property> + <property name="value" > + <number>0</number> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="0" column="2" > + <widget class="QSpinBox" name="redSpinBox" > + <property name="maximum" > + <number>255</number> + </property> + </widget> + </item> + <item row="1" column="0" > + <widget class="QLabel" name="label_6" > + <property name="text" > + <string>Green</string> + </property> + </widget> + </item> + <item row="1" column="1" > + <widget class="QSlider" name="greenSlider" > + <property name="minimum" > + <number>0</number> + </property> + <property name="maximum" > + <number>255</number> + </property> + <property name="value" > + <number>0</number> + </property> + <property name="sliderPosition" > + <number>0</number> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="1" column="2" > + <widget class="QSpinBox" name="greenSpinBox" > + <property name="maximum" > + <number>255</number> + </property> + </widget> + </item> + <item row="2" column="0" > + <widget class="QLabel" name="label_7" > + <property name="text" > + <string>Blue</string> + </property> + </widget> + </item> + <item row="2" column="1" > + <widget class="QSlider" name="blueSlider" > + <property name="minimum" > + <number>0</number> + </property> + <property name="maximum" > + <number>255</number> + </property> + <property name="value" > + <number>99</number> + </property> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="2" column="2" > + <widget class="QSpinBox" name="blueSpinBox" > + <property name="maximum" > + <number>255</number> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QWidget" native="1" name="widget_2" > + <layout class="QFormLayout" name="formLayout" > + <property name="margin" > + <number>1</number> + </property> + <item row="0" column="0" > + <widget class="QLabel" name="label" > + <property name="text" > + <string>Composition Mode</string> + </property> + </widget> + </item> + <item row="0" column="1" > + <widget class="QComboBox" name="compositionModeBox" > + <item> + <property name="text" > + <string>Screen</string> + </property> + </item> + <item> + <property name="text" > + <string>Overlay</string> + </property> + </item> + <item> + <property name="text" > + <string>Multiply</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer" > + <property name="orientation" > + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0" > + <size> + <width>20</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>redSlider</sender> + <signal>valueChanged(int)</signal> + <receiver>redSpinBox</receiver> + <slot>setValue(int)</slot> + <hints> + <hint type="sourcelabel" > + <x>214</x> + <y>100</y> + </hint> + <hint type="destinationlabel" > + <x>271</x> + <y>103</y> + </hint> + </hints> + </connection> + <connection> + <sender>greenSlider</sender> + <signal>valueChanged(int)</signal> + <receiver>greenSpinBox</receiver> + <slot>setValue(int)</slot> + <hints> + <hint type="sourcelabel" > + <x>214</x> + <y>128</y> + </hint> + <hint type="destinationlabel" > + <x>271</x> + <y>131</y> + </hint> + </hints> + </connection> + <connection> + <sender>blueSlider</sender> + <signal>valueChanged(int)</signal> + <receiver>blueSpinBox</receiver> + <slot>setValue(int)</slot> + <hints> + <hint type="sourcelabel" > + <x>214</x> + <y>156</y> + </hint> + <hint type="destinationlabel" > + <x>271</x> + <y>159</y> + </hint> + </hints> + </connection> + <connection> + <sender>redSpinBox</sender> + <signal>valueChanged(int)</signal> + <receiver>redSlider</receiver> + <slot>setValue(int)</slot> + <hints> + <hint type="sourcelabel" > + <x>271</x> + <y>103</y> + </hint> + <hint type="destinationlabel" > + <x>214</x> + <y>100</y> + </hint> + </hints> + </connection> + <connection> + <sender>greenSpinBox</sender> + <signal>valueChanged(int)</signal> + <receiver>greenSlider</receiver> + <slot>setValue(int)</slot> + <hints> + <hint type="sourcelabel" > + <x>271</x> + <y>131</y> + </hint> + <hint type="destinationlabel" > + <x>214</x> + <y>128</y> + </hint> + </hints> + </connection> + <connection> + <sender>blueSpinBox</sender> + <signal>valueChanged(int)</signal> + <receiver>blueSlider</receiver> + <slot>setValue(int)</slot> + <hints> + <hint type="sourcelabel" > + <x>271</x> + <y>159</y> + </hint> + <hint type="destinationlabel" > + <x>214</x> + <y>156</y> + </hint> + </hints> + </connection> + <connection> + <sender>tintButton</sender> + <signal>toggled(bool)</signal> + <receiver>redSlider</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>40</x> + <y>65</y> + </hint> + <hint type="destinationlabel" > + <x>62</x> + <y>89</y> + </hint> + </hints> + </connection> + <connection> + <sender>tintButton</sender> + <signal>toggled(bool)</signal> + <receiver>greenSlider</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>58</x> + <y>65</y> + </hint> + <hint type="destinationlabel" > + <x>63</x> + <y>120</y> + </hint> + </hints> + </connection> + <connection> + <sender>tintButton</sender> + <signal>toggled(bool)</signal> + <receiver>blueSlider</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>80</x> + <y>65</y> + </hint> + <hint type="destinationlabel" > + <x>93</x> + <y>147</y> + </hint> + </hints> + </connection> + <connection> + <sender>tintButton</sender> + <signal>toggled(bool)</signal> + <receiver>redSpinBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>239</x> + <y>64</y> + </hint> + <hint type="destinationlabel" > + <x>246</x> + <y>89</y> + </hint> + </hints> + </connection> + <connection> + <sender>tintButton</sender> + <signal>toggled(bool)</signal> + <receiver>greenSpinBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>262</x> + <y>65</y> + </hint> + <hint type="destinationlabel" > + <x>263</x> + <y>118</y> + </hint> + </hints> + </connection> + <connection> + <sender>tintButton</sender> + <signal>toggled(bool)</signal> + <receiver>blueSpinBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel" > + <x>230</x> + <y>64</y> + </hint> + <hint type="destinationlabel" > + <x>251</x> + <y>151</y> + </hint> + </hints> + </connection> + </connections> +</ui> |